package valuer

import (
	"database/sql"
	"go-demo/orm/interval/errs"
	"go-demo/orm/model"
	"reflect"
	"unsafe"
)

type reflectValue struct {
	model  *model.Model
	entity any // 要访问的对象
}

func (u reflectValue) SetColumns(rows *sql.Rows) error {
	columns, err := rows.Columns() // 先拿到结果集的列
	if err != nil {
		return err
	}
	vals := make([]interface{}, 0, len(columns))
	tpAddress := reflect.ValueOf(u.entity).UnsafePointer() // 计算对象的起始地址
	for _, col := range columns {
		cm, ok := u.model.ColumnMap[col]
		if !ok {
			return errs.NewErrUnknownColumn(col)
		}
		// 字段的地址 = 对象的起始地址 + 偏移量
		fdAddress := unsafe.Pointer(uintptr(tpAddress) + cm.Offset)
		// 反射在特定的地址上，创建一个特定类型的实例 该实例是原本类型的指针类型
		// 例如 fd.Type = int，那么val 是 *int
		val := reflect.NewAt(cm.Type, fdAddress)
		vals = append(vals, val.Interface())

	}
	if err = rows.Scan(vals...); err != nil {
		return err
	}
	return nil
}

var _ Creator = NewReflectValue

func NewReflectValue(model *model.Model, val any) Value {
	return reflectValue{
		model:  model,
		entity: val,
	}
}
